package com.zrkizzy.module.system.service.config;

import com.zrkizzy.common.core.utils.bean.BeanCopyUtil;
import com.zrkizzy.common.models.domain.system.config.SystemConfig;
import com.zrkizzy.common.models.dto.system.config.SystemConfigDTO;
import com.zrkizzy.common.redis.service.IRedisService;
import com.zrkizzy.module.system.exception.SystemErrorCode;
import com.zrkizzy.module.system.mapper.config.SystemConfigMapper;
import com.zrkizzy.system.facade.service.config.ISystemConfigService;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.zrkizzy.common.redis.enums.RedisKey.CONFIG_BASIC_KEY;

/**
 * <p>
 * 系统配置业务逻辑接口实现类
 * </p>
 *
 * @author zhangrongkang
 * @since 2023/7/21
 */
@Service
@Slf4j
public class SystemConfigServiceImpl implements ISystemConfigService {

    @Autowired
    private IRedisService redisService;

    @Autowired
    private SystemConfigMapper systemConfigMapper;

    /**
     * 获取所有系统配置
     *
     * @return 系统配置实体
     */
    @Override
    public SystemConfig getSystemConfig() {
        // 从Redis中获取基本配置信息
        SystemConfig systemConfig = redisService.get(CONFIG_BASIC_KEY.getKey(), SystemConfig.class);
        if (null == systemConfig) {
            // 从数据库中获取基本配置信息
            systemConfig = loadBasicConfig();
        }
        return systemConfig;
    }

    /**
     * 更新系统基本配置
     *
     * @param systemConfigDTO 系统配置数据接收对象
     * @return 是否更新成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveConfig(SystemConfigDTO systemConfigDTO) {
        // 转换数据接收对象
        SystemConfig systemConfig = BeanCopyUtil.copy(systemConfigDTO, SystemConfig.class);
        int row = systemConfigMapper.updateById(systemConfig);
        if (row != 1) {
            // 抛出更新失败异常
            throw SystemErrorCode.SYSTEM_CONFIG_UPDATE_ERROR.exception();
        }
        // 采取先更新数据库再更新Redis策略，清除掉Redis中存储的配置信息
        redisService.del(CONFIG_BASIC_KEY.getKey());
        // 存储新的键值到Redis中，仍然为永不过期
        redisService.set(CONFIG_BASIC_KEY.getKey(), systemConfig);
        // 返回操作成功
        return Boolean.TRUE;
    }

    /**
     * 获取系统基本配置信息
     *
     * @return 基本信息返回对象
     */
    @PostConstruct
    private SystemConfig loadBasicConfig() {
        // 获取基本配置信息
        SystemConfig systemConfig = systemConfigMapper.selectList(null).getFirst();
        // 存储到Redis中，并设置永不过期
        redisService.set(CONFIG_BASIC_KEY.getKey(), systemConfig);
        // 返回配置信息
        return systemConfig;
    }

}
